﻿using LearningEnglish.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace LearningEnglish.ViewModels
{
    public class TokenRD
    {
        public TokenRD(Guid id, Guid entityID, Token.Channel channel, bool isExclusive, TimeSpan liveTime)
        {
            ID = id;
            EntityID = entityID;
            Channel = channel;
            IsExclusive = isExclusive;
            LiveTime = liveTime;
            Tickets = new List<TokenRDTicket>();
        }

        /// <summary>
        /// 添加票据
        /// <para>当为独占时，则只有本次添加有效</para>
        /// <para>当不为独占时，则不会对以往票据造成影响</para>
        /// </summary>
        /// <param name="value"></param>
        /// <param name="startTime"></param>
        public void AddTicket(Guid value, DateTime startTime)
        {
            if (IsExclusive)
                Tickets.ForEach(x => x.IsPass = true);

            var ticket = new TokenRDTicket(value, startTime, LiveTime);
            Tickets.Add(ticket);
        }

        /// <summary>
        /// 依据独占属性，刷新票据
        /// <para>当为独占时，会强制刷新本渠道所有票据</para>
        /// <para>当不为独占时，则只会刷新指定票据</para>
        /// </summary>
        public void Refresh(Guid ticket)
        {
            if (IsExclusive)
                Tickets.ForEach(x => x.IsPass = true);
            else
            {
                Tickets.ForEach(x =>
                {
                    if (x.Value == ticket)
                        x.IsPass = true;
                });
            }
        }

        /// <summary>
        /// 强制刷新票据
        /// </summary>
        public void ForceRefresh()
        {
            Tickets.ForEach(x => x.IsPass = true);
        }

        /// <summary>
        /// 检查该票据是否属于该Token
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Has(Guid value)
        {
            return Tickets.Exists(x => x.Value == value);
        }

        /// <summary>
        /// 检查该票据是否超时
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool IsTimeOut(Guid value)
        {
            if (Tickets.Count == 0)
                throw new Exception("该Token无可用票据 " + Channel);
            if (!Tickets.Exists(x => x.Value == value))
                throw new Exception("该票据不属于该Token");

            var ticket = (from p in Tickets where p.Value == value select p).Single();

            return ticket.IsTimeOut();
        }

        public Guid ID { get; set; }
        public Guid EntityID { get; set; }

        public bool IsExclusive { get; set; }

        public TimeSpan LiveTime { get; set; }

        public List<TokenRDTicket> Tickets { get; set; }

        public Token.Channel Channel { get; set; }

        public static Dictionary<Guid, bool> GlobalConfig = new Dictionary<Guid, bool>();
    }

    public class TokenRDTicket
    {
        public TokenRDTicket(Guid value, DateTime startTime, TimeSpan liveTime)
        {
            Value = value;
            StartTime = startTime;
            LiveTime = liveTime;
            IsPass = false;
        }

        public Guid Value { get; set; }
        public DateTime StartTime { get; set; }

        /// <summary>
        /// 票据存活时间
        /// </summary>
        public TimeSpan LiveTime { get; set; }

        /// <summary>
        /// 该属性指示票据是否作废。
        /// 该属性用于强制作废票据，即当该属性被设置为true时，即使没有超时，IsTimeOut方法也会返回true，表示已超时
        /// </summary>
        public bool IsPass { get; set; }

        public bool IsTimeOut()
        {
            if (IsPass)
                return true;

            if (StartTime.Add(LiveTime) >= DateTime.Now)
                return false;
            return true;
        }
    }
}